package com.wanjia.estate.utils;

import lombok.AccessLevel;
import lombok.NoArgsConstructor;
import lombok.extern.slf4j.Slf4j;

import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.function.Supplier;

@NoArgsConstructor(access = AccessLevel.PRIVATE)
@Slf4j
public final class RepeatUtil {

    public static final String REPEAT_EXCEPTION = "重复调用异常";

    public static <T, S> S repeat(int limit, boolean ignoreException, T t, Function<T, S> function, Predicate<S> predicate) {
        for (int i = 0; i < limit; i++) {
            try {
                S s = function.apply(t);
                if (predicate.test(s)) {
                    return s;
                }
            } catch (Exception e) {
                log.error(REPEAT_EXCEPTION, e);
                if (!ignoreException) {
                    throw e;
                }
            }
        }

        return null;
    }

    public static <S> S repeat(int limit, boolean ignoreException, Supplier<S> supplier, Predicate<S> predicate) {

        for (int i = 0; i < limit; i++) {
            try {
                S s = supplier.get();
                if (predicate.test(s)) {
                    return s;
                }
            } catch (Exception e) {
                log.error(REPEAT_EXCEPTION, e);
                if (!ignoreException) {
                    throw e;
                }
            }
        }

        return null;
    }

    public static <T> void repeat(int limit, T t, Consumer<T> consumer) {

        for (int i = 0; i < limit; i++) {
            try {
                consumer.accept(t);
            } catch (Exception e) {
                log.error(REPEAT_EXCEPTION, e);
            }
        }

        throw new NullPointerException("重复调用失败");
    }
}
